{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 图像基本操作"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 访问像素值并修改它们\n",
    "- 访问图像属性\n",
    "- 设置感兴趣区域（ROI）\n",
    "- 拆分和合并图像"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Administrator\\Desktop\n"
     ]
    }
   ],
   "source": [
    "cd C:\\Users\\Administrator\\Desktop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import cv2\n",
    "\n",
    "img = cv2.imread('test.jpg')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 获取并修改像素值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([199, 227, 210], dtype=uint8)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#  it returns an array of Blue, Green, Red values\n",
    "img[100, 100]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "219"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# For grayscale image, just corresponding intensity is returned\n",
    "gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n",
    "gray[100, 100]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([255, 255, 255], dtype=uint8)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "img[101, 101] = [255, 255, 255]\n",
    "img[101, 101]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "numpy是经过优化了的进行快速矩阵运算的包，所以不推荐逐个获取像素值并修改能矩阵运算就不要用循环。\n",
    "\n",
    "例如前5行的后3列，用numpy的array.item()和array.itemset()会更好。但是返回是标量，如果想获得所有RGB的值，需要使用array.item()分割他们。\n",
    "更好的方法是"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "210\n",
      "100\n"
     ]
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy\n",
    "\n",
    "img = cv2.imread('test.jpg')\n",
    "print(img.item(10, 10, 2))\n",
    "img.itemset((10, 10, 2), 100)\n",
    "print(img.item(10, 10, 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 获取图像属性\n",
    "图像属性包括：行，列，通道，图像数据类型，像素数目等"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(472, 643, 3)\n"
     ]
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy\n",
    "\n",
    "img = cv2.imread('test.jpg')\n",
    "print(img.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "910488\n"
     ]
    }
   ],
   "source": [
    "# 返回图像的像素数目\n",
    "print(img.size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "uint8\n"
     ]
    }
   ],
   "source": [
    "# 数据类型\n",
    "print(img.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 图像ROI\n",
    "对图像的特定区域操作。ROI是使用numpy索引来获得的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(212, 347, 3)\n"
     ]
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy\n",
    "\n",
    "img = cv2.imread('roi.jpg')\n",
    "print(img.shape)\n",
    "\n",
    "ball = img[180:210, 30:60]\n",
    "img[120:150, 90:120] = ball"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 拆分及合并图像通道"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "警告：\n",
    "\n",
    "cv2.split 时间消耗较大，需要时尽可能选择 Numpy 的索引操作会更快"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[240, 228, 250, ..., 251, 220, 250],\n",
       "       [239,  55,  32, ...,  52,  78, 233],\n",
       "       [246,  29,  28, ...,  38,  50, 250],\n",
       "       ...,\n",
       "       [212,  74,  71, ...,  82,  93, 231],\n",
       "       [210,  72,  68, ...,  80,  91, 230],\n",
       "       [210,  72,  67, ...,  77,  89, 229]], dtype=uint8)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b, g, r = cv2.split(img)  #拆分\n",
    "b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "img = cv2.merge((b, g, r))  #合并"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "或者"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[240, 228, 250, ..., 251, 220, 250],\n",
       "       [239,  55,  32, ...,  52,  78, 233],\n",
       "       [246,  29,  28, ...,  38,  50, 250],\n",
       "       ...,\n",
       "       [212,  74,  71, ...,  82,  93, 231],\n",
       "       [210,  72,  68, ...,  80,  91, 230],\n",
       "       [210,  72,  67, ...,  77,  89, 229]], dtype=uint8)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "b = img[:, :, 0]\n",
    "b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 为图像扩边（填充）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "想为图像周围建一个边可以使用**cv2.copyMakeBorder()**函数。这经常在**卷积运算或0填充时**被用到。具体参数如下：\n",
    "- 5.1 src输入图像\n",
    "- top,bottom,left,right对应边界的像素数目\n",
    "- borderType要添加哪种类型的边界：\n",
    "    - cv2.BORDER_CONSTANT添加有颜色的常数值边界，还需要下一个参数（value）\n",
    "    - cv2.BORDER_REFLIECT边界元素的镜像。例如：fedcba | abcdefgh | hgfedcb\n",
    "    - cv2.BORDER_101或者cv2.BORDER_DEFAULT跟上面一样，但稍作改动，例如：gfedcb | abcdefgh | gfedcba\n",
    "    - cv2.BORDER_REPLICATE重复最后一个元素。例如: aaaaaa| abcdefgh|hhhhhhh\n",
    "    - cv2.BORDER_WRAP 不知怎么了, 就像样: cdefgh| abcdefgh|abcdefg\n",
    "- value边界颜色"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2 as cv\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "BLUE = [255, 0, 0]\n",
    "img1 = cv.imread('rio.jpg')\n",
    "replicate = cv.copyMakeBorder(img1, 10, 10, 10, 10, cv.BORDER_REPLICATE)\n",
    "reflect = cv.copyMakeBorder(img1, 10, 10, 10, 10, cv.BORDER_REFLECT)\n",
    "reflect101 = cv.copyMakeBorder(img1, 10, 10, 10, 10, cv.BORDER_REFLECT_101)\n",
    "wrap = cv.copyMakeBorder(img1, 10, 10, 10, 10, cv.BORDER_WRAP)\n",
    "constant = cv.copyMakeBorder(\n",
    "    img1, 10, 10, 10, 10, cv.BORDER_CONSTANT, value=BLUE)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.subplot(231), plt.imshow(img1, 'gray'), plt.title('ORIGINAL')\n",
    "plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')\n",
    "plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')\n",
    "plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')\n",
    "plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')\n",
    "plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 图像上的算术运算"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 图像加法\n",
    "使用cv2.add()将两幅图像进行加法运算，也可以直接使用numpy，res=img1+img2.两幅图像的大小，类型必须一致，或者第二个图像可以是一个简单的标量值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[255]]\n"
     ]
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "\n",
    "x=np.uint8([250])\n",
    "y=np.uint8([10])\n",
    "\n",
    "print(cv2.add(x,y))#250+10=260>=255"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4]\n"
     ]
    }
   ],
   "source": [
    "print (x+y)#250+10=260%255=4"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "OpenCV的结果会更好，so尽量使用OpenCV中的函数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 图像混合\n",
    "这也是加法，不同的是两幅图像的权重不同，这会给人一种混合或者透明的感觉。图像混合的计算公式如下：\n",
    "\n",
    "g(x) = (1−α)f0 (x)+αf1 (x)\n",
    "\n",
    "通过修改α的值（0-->1）,可以实现很酷的混合。\n",
    "\n",
    "例：将两幅图像混合，第一幅权重为0.7.第二幅权重为0.3。函数cv2.addWeighed()可以按下面的公式对图片进行混合。\n",
    "\n",
    "dst = α·img1 + β·img2+γ\n",
    "\n",
    "这里γ的取值为0.\n",
    "\n",
    "```python\n",
    "import cv2\n",
    "import numpy as np\n",
    "img1 = cv2.imread('45.jpg')\n",
    "img2 = cv2.imread('messigray.png')\n",
    "\n",
    "dst = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)\n",
    "\n",
    "cv2.imshow('dst', dst)\n",
    "cv2.waitKey(0)\n",
    "cv2.destroyAllWindows()\n",
    "```\n",
    "![](https://docs.opencv.org/4.1.0/blending.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 按位运算\n",
    "这里包括按位操作有：AND，OR，NOT，XOR等，当我们提取图像的一部分，选择非矩形ROI时，会很有用（下章）。下面进行如何改变一幅图的特定区域。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "\n",
    "img1 = cv2.imread('45.jpg')\n",
    "img2 = cv2.imread('messigray.png')\n",
    "\n",
    "# I want to put logo on top-left corner, So I create a ROI\n",
    "rows, cols, channels = img2.shape\n",
    "roi = img1[0:rows, 0:cols]\n",
    "\n",
    "# Now create a mask of logo and create its inverse mask also\n",
    "img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)\n",
    "# 二值化\n",
    "ret, mask = cv2.threshold(img2gray, 175, 255, cv2.THRESH_BINARY)\n",
    "mask_inv = cv2.bitwise_not(mask)\n",
    "\n",
    "# Now black-out the area of logo in ROI\n",
    "#取ROI中与mask中不为零的值对应的像素的值，其让值为0 。\n",
    "#注意这里必须有mask=mask或者mask=mask_inv，其中mask=不能忽略\n",
    "img1_bg = cv2.bitwise_and(roi, roi, mask=mask)\n",
    "\n",
    "#取roi中与mask_inv中不为零的值对应的像素的值，其他值为0\n",
    "# Take only region of logo from logo image.\n",
    "img2_fg = cv2.bitwise_and(img2, img2, mask=mask_inv)\n",
    "\n",
    "# Put logo in ROI and modify the main image\n",
    "dst = cv2.add(img1_bg, img2_fg)\n",
    "img1[0:rows, 0:cols] = dst\n",
    "\n",
    "cv2.imshow('res', img1)\n",
    "cv2.waitKey(0)\n",
    "cv2.destroyAllWindows()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](https://docs.opencv.org/4.1.0/overlay.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 程序性能检测及优化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用OpenCV检测程序效率"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "涉及函数 **cv2.getTickCount，cv2.getTickFrequency**\n",
    "\n",
    "1.使用OpenCV检测程序效率\n",
    "cv2.getTickCount函数返回从参考点到这个函数被执行的时钟数。在一个函数执行前后都调用它，可以得到这个函数的执行时间。\n",
    "\n",
    "cv2.getTickFrequency返回时钟频率，或者说每秒钟的时钟数\n",
    "例，窗口大小不同（5,7,9）的核函数来做中值滤波，查看一个函数运行了多少秒"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.00020842450332101035\n"
     ]
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "\n",
    "img = cv2.imread('roi.jpg')\n",
    "\n",
    "e1 = cv2.getTickCount()\n",
    "for i in range(5, 49, 2):\n",
    "    img = cv2.medianBlur(img, i)\n",
    "e2 = cv2.getTickCount()\n",
    "time = (e2 - e1) / cv2.getTickFrequency()\n",
    "print(time)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2648441.0"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cv2.getTickFrequency()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## OpenCV中的默认优化\n",
    "cv2.useOptimized()来查看优化是否被开启，cv2.setUesOptimized()来开启优化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import cv2 \n",
    "import numpy as np\n",
    "\n",
    "# check if optimization is enabled \n",
    "cv2.useOptimized()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "729 ns ± 107 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit res = cv2.medianBlur(img, 49) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Disable it \n",
    "cv2.setUseOptimized(False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cv2.useOptimized()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "782 ns ± 77.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit res = cv2.medianBlur(img,49)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 在IPython中检测程序效率"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "\n",
    "x =5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "418 ns ± 47.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit y=x**2 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "67.2 ns ± 6.29 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit y=x*x "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "646 ns ± 60.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
     ]
    }
   ],
   "source": [
    "z = np.uint8([5])\n",
    "\n",
    "%timeit y=z*z "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "621 ns ± 53.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit y=np.square(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**注意**：Python 的标算比 Nump 的标算快。对于仅包含一两个 元素的操作 Python 标比 Numpy 的数组快。但是当数组稍微大一点时 Numpy 就会胜出了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "622 ns ± 101 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit z = cv2.countNonZero(img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.25 µs ± 78.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%timeit z = np.count_nonzero(img)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "See, OpenCV function is nearly 25x faster than Numpy function."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 效率优化技术\n",
    "有些技术和编程方法可以我们大的发挥 Python 和 Numpy 的威力。 我们仅仅提一下相关的你可以接查找更多细信息。我们 的的一点是先用简单的方式实现你的算法结果正确当结 果正确后再使用上的提到的方法找到程序的瓶来优化它。\n",
    "\n",
    "- 尽免使用循环尤其双层三层循环它们天生就是常慢的。\n",
    "- 算法中尽使用向操作因为 Numpy 和 OpenCV 对向操作 了优化。\n",
    "- 利用缓存一致性。\n",
    "- 没有必的就不复制数组。使用图来代替复制。数组复制是常浪源的。\n",
    "就算了上优化如果你的程序是很慢或者大的不可免的 你你应尝使用其他的包比如 Cython来加你的程序。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. [Python Optimization Techniques](http://wiki.python.org/moin/PythonSpeed/PerformanceTips)\n",
    "2. Scipy Lecture Notes - [Advanced Numpy](http://scipy-lectures.github.io/advanced/advanced_numpy/index.html#advanced-numpy)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "'Python Interactive'",
   "language": "python",
   "name": "e9378e17-d59e-493e-9710-f34e5f2d08ca"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
